'
+ '
'
+ character.get('name')+' would like to move to '+destNotes+' on '+page.get('name').replace(/\[[^\[\]]*\]/g,'').trim()+'. If this move is correct, please approve the move.'
+ '
' + button + '
'
+ '
';
sendChat('Page Navigator','/w "'+msgTarget+'"'+msg,null,{noarchive:true});
},
//Moves the designated players to the designated page, and generates tokens at the designated destination if provided.
// string Array string string
moveToPage = function(id,players,pageId,destination){
var party = [],
separated = Campaign().get('playerspecificpages')||{},
who = idToDisplayName(id),
gm=playerIsGM(id),
folders;
if(pageId==='return'){
pageId=Campaign().get('playerpageid');
}
if(!findObjs({type:'page',id:pageId})){
return;
}
folders=getObj('page',pageId).get('name').match(/(?:\[([^\[\]]+)\])/g)||[];
folders.push('All');
//4220
if(!_.some(folders,(f)=>{return folderAccess[f]==='players'}) && !gm){
//Handling for inaccessible page
return;
}
if(_.some(players,(p)=>{return p.match(/whole/)}) && (gm || state.PAGENAVIGATOR.control==='whole')){
if(state.PAGENAVIGATOR.teleport === 'on'){
if(destination && destination !== '-'){
_.each(allPlayers,(p)=>{
party.push(p.id);
});
findEntrance(party,pageId,destination);
}
}
Campaign().set({playerspecificpages:false,playerpageid:pageId});
}else if(_.some(players,(p)=>{return p.match(/current/)}) && (gm || state.PAGENAVIGATOR.control==='whole' || state.PAGENAVIGATOR.control==='current')){
if(state.PAGENAVIGATOR.teleport === 'on'){
if(destination && destination !== '-'){
_.each(allPlayers,(p)=>{
if(!separated[p.id] || separated[p.id]===false){
party.push(p.id);
}
});
findEntrance(party,pageId,destination);
}
}
Campaign().set('playerpageid',pageId);
}else{
_.each(players,(p)=>{
party.push(p);
separated[p]=pageId;
});
if(state.PAGENAVIGATOR.teleport === 'on'){
findEntrance(party,pageId,destination);
}
Campaign().set('playerspecificpages',false);
Campaign().set('playerspecificpages',separated);
}
},
//generates query message to choose where to move (page &/or landing) to move designated players
// string string array string string
moveQuery = function(id,action,players,page,landing){
var button,msg,
command = '!nav --'+action+',pageID=',
playerQuery = '?{Who is moving?|All Players,whole|Current Party,current}',
destQuery='',
folderKeys,destName,
who = idToDisplayName(id),
gm=playerIsGM(id),
folders;
if(!players || players.length===0){
help(id);
return;
}
msg = '
'
+ '
'
+ 'Please specify where you would like to '+action+' the following players:
'+_.map(players,(p)=>{return idToDisplayName(p);}).join(', ')+'
'
+ '
';
if(page && landing === '?'){
folders=getObj('page',page).get('name').match(/(?:\[([^\[\]]+)\])/g)||[];
folders.push('All');
if(_.some(folders,(f)=>{return folderAccess[f]==='players'}) || gm){
command+=page;
}else{
sendChat('Page Navigator','/w "'+who+'" That page is not accessible to players, please ask your gm to move you.',null,{noarchive:true});
return;
}
destQuery+='landing=?{Where should tokens be created|-';
_.each(destTokens[page],(t)=>{
destQuery += '|';
destQuery += t.parsedGM['location'];
});
destQuery += '|}';
command+=destQuery;
button = makeButton(
command+'|'+players.join('|'),
'Specify Destination', '#009900', '#000000'
);
msg+= button + '
'
+ '
';
}else if(!page){
folders=getObj('page',Campaign().get('playerpageid')).get('name').match(/(?:\[([^\[\]]+)\])/g)||[];
folders.push('All');
if(_.some(folders,(f)=>{return folderAccess[f]==='players'}) || gm){
if(landing==='?'){
destQuery=',landing=?{Where should tokens be created|-';
_.each(destTokens[Campaign().get('playerpageid')],(t)=>{
if(t.parsedGM.location){
destQuery+='|'+t.parsedGM.location;
}
});
destQuery+='}';
}
msg+=makeButton(
command+'return'+destQuery+'|'+players.join('|'),
'Return to '+getObj('page',Campaign().get('playerpageid')).get('name').replace(/(?:\[([^\[\]]+)\])/g,'').trim(), '#009900', '#000000'
);
}
folderKeys = _.keys(allFolders);
_.each(folderKeys,(k)=>{
if(folderAccess[k]==='players'||gm){
if(allFolders[k].length>0){
var pageQuery = '?{Which page in folder '+k;
_.each(allFolders[k],(n)=>{
page = _.filter(allPages,(p)=>{
return p.id===n;
})[0];
pageQuery+='|'+page.get('name').replace(/(?:\[([^\[\]]+)\])/g,'').trim()+','+page.id;
if(landing==='?'){
destQuery=',landing=?{Where should tokens be created|-';
_.each(destTokens[page.id],(t)=>{
if(t.parsedGM['location']){
destQuery += '|'+t.parsedGM['location'];
}
});
destQuery+='|}';
pageQuery += HE(destQuery);
}
});
}
pageQuery+='|}';
msg+=makeButton(
command+HE(pageQuery)+'|'+players.join('|'),
k+' folder', '#009900', '#000000'
);
}
/*if(landing==='?'){
if(folderAccess[k]==='players'||gm){
if(allFolders[k].length>0){
folderQuery+='|'+k+',';
_.each(allFolders[k],(n)=>{
page = _.filter(allPages,(p)=>{
return p.id===n;
})[0];
_.each(destTokens[page.id],(t)=>{
destQuery += '|';
destQuery += t.parsedGM['location'];
});
destQuery += '|}';
folderQuery+=HE(page.get('name').replace(/\[[^\[\]]*\]/g,'').trim()+HE(HE(','))+page.id+HE(',landing='+destQuery));
});
}
}
}else{
if(folderAccess[k]==='players'||gm){
if(folderAccess[k]==='players'||gm){
folderQuery+='|'+k+','+HE('?{Which Page|');
_.each(allFolders[k],(n)=>{
page = _.filter(allPages,(p)=>{
return p.id===n;
})[0];
folderQuery+=HE(page.get('name').replace(/\[[^\[\]]*\]/g,'').trim()+','+page.id+'|');
});
folderQuery+=HE('}');
}
}
}*/
});
msg+='
';
}
sendChat('Page Navigation','/w "'+who+'" '+msg,null,{noarchive:true});
},
//inserts the value in the string in front of the index
/*insert = function (str, index, value) {
return str.substr(0, index) + value + str.substr(index);
},*/
teleportConfig = function(){
var teleportMsg='
',//Teleport section start div
teleportButton,removalButton,playerButton,characters,charQuery,petQuery;
if(state.PAGENAVIGATOR.teleport === 'on'){
teleportButton = makeButton(
'!nav --config,teleport=off --config',
'On', 'green'
);
if(state.PAGENAVIGATOR.removal === 'on'){
removalButton = makeButton(
'!nav --config,remove=off --config',
'On','green'
);
}else{
removalButton = makeButton(
'!nav --config,remove=on --config',
'Off','red','black'
);
}
teleportMsg+='Teleportation is
'+teleportButton+'
'
+'Token Removal is
'+removalButton+'
';
_.each(allPlayers,function(p){
charQuery = '|';
petQuery = '';
characters = _.filter(findObjs({type: 'character',}), (c)=>{
return _.contains(c.get('controlledby').split(','),p.id);
});
_.each(characters, function(c){
charQuery += '|' + c.get('name') + ',' + c.id;
});
petQuery += '?{Primary Character'+charQuery+'}|'
+' ?{Number of followers'
+'|1,'+HE('?{Follower 1'+charQuery+'|none}')
+'|2,'+HE('?{Follower 1'+charQuery+'|none}|?{Follower 2'+charQuery+'}')
+'|3,'+HE('?{Follower 1'+charQuery+'|none}|?{Follower 2'+charQuery+'|none}|?{Follower 3'+charQuery+'|none}')
+'|4,'+HE('?{Follower 1'+charQuery+'|none}|?{Follower 2'+charQuery+'|none}|?{Follower 3'+charQuery+'|none}|?{Follower 4'+charQuery+'|none}')
+'|5,'+HE('?{Follower 1'+charQuery+'|none}|?{Follower 2'+charQuery+'|none}|?{Follower 3'+charQuery+'|none}|?{Follower 4'+charQuery+'|none}|?{Follower 5'+charQuery+'|none}')
+'}';
charQuery+='|Has pets/followers,';
playerButton = makeButton(
'!nav --config,tokens=' + p.id + '|?{'+p.get('displayname')+"'s default character"+charQuery+HE(HE(petQuery))+'} --config',
'Set Default Token', 'white', 'black'
);
teleportMsg+=p.get('displayname')
+'
'
+playerButton+'
';
});
}else{
teleportButton = makeButton(
'!nav --config,teleport=on --config',
'Teleport Off', 'gray','white'
);
teleportMsg+=teleportButton;
}
teleportMsg+='
';//telport section end div
return teleportMsg;
},
controlConfig = function(){
var controlMsg = '
'
+'Players can move:',
controlButton,accessButton;
//Handling for setting ability of players to transition other players
switch(state.PAGENAVIGATOR.control) {
case 'whole':
controlButton = makeButton(
'!nav --config,control=?{Players can move all players. Who should they be able to move|Current Party only,current|Only Themselves,self} --config',
'
The Whole Party', '#228b22'
);
break;
case 'current':
controlButton = makeButton(
'!nav --config,control=?{Players can move only the current party. Who should they be able to move|All players,whole|Only Themselves,self} --config',
'
The Current Party', '#ffff00', '#000000'
);
break;
case 'self':
controlButton = makeButton(
'!nav --config,control=?{Players can move only themselves. Who should they be able to move|All players,whole|Current Party only,current} --config',
'
Themselves Only', '#ff4500'
);
break;
}
controlMsg+='
'+controlButton+'
';
//Page Access
controlMsg+=folderConfig();
return controlMsg;
},
folderConfig = function(){
var folderMsg = '
'
+'Folders are either Player (GREEN) or GM only (WHITE) accessible.
',
folderButton,
acc={
'gm':'players',
'players':'gm'
},
accColor = {
'gm':'transparent',
'players':'green'
};
_.each(_.keys(folderAccess),(k)=>{
folderButton = makeButton(
'!nav --config,folder='+k+',access='+acc[folderAccess[k]]+' --config',
''+k+'', accColor[folderAccess[k]],'black'
);
folderMsg+=folderButton;
});
folderMsg+='
';
return folderMsg;
},
markerConfig = function(){
var dmarkerButton = '',
markerMsg='
'//markermsg div start
+'
Destination tokens are marked by:
';
_.each(statusquery, function(s){
dmarkerButton += makeStatusButton(s);
});
markerMsg += dmarkerButton+'
';//end marker msg div
return markerMsg;
},
configAssembler = function(who){
var teleportMsg = teleportConfig(),
controlMsg = controlConfig(),
markerMsg = markerConfig(),
menu = '/w "'+who+'"
'//overall div for nice formatting of control panel
+'
'//Control Panel Header div
+'Page Navigator v'+version+' Options'
+'
';//end Control Panel Header div
menu+=controlMsg+markerMsg+teleportMsg;
menu+='
'//end overall div
sendChat('',menu,null,{noarchive:true});
},
//gets the current states, and outputs everything in a nicely formatted config screen
configHandler = function(id,cmdDetails){
var msg ='',
dmarkerButton = '',
updateButton = makeButton('!nav update', '
Update Destinations & Pages', '#fff8dc', '#191970'),
who = idToDisplayName(id);
switch(false){
case _.isUndefined(cmdDetails.details.remove):
if(cmdDetails.details.remove==='on'||cmdDetails.details.remove==='off'){
state.PAGENAVIGATOR.removal = cmdDetails.details.remove;
}else{
//handling for improper setting
}
break;
case _.isUndefined(cmdDetails.details.folder):
if(_.contains(_.keys(folderAccess),cmdDetails.details.folder) && (cmdDetails.details.access==='players'||cmdDetails.details.access==='gm')){
folderAccess[cmdDetails.details.folder]=cmdDetails.details.access;
folderAbility.set('description',folderAccess);
}
break;
case _.isUndefined(cmdDetails.details.control):
if(cmdDetails.details.control==='whole'||cmdDetails.details.control==='current'||cmdDetails.details.control==='self'){
state.PAGENAVIGATOR.control = cmdDetails.details.control;
}else{
//handling for improper setting
}
break;
case _.isUndefined(cmdDetails.details.dMarker):
if(_.contains(statusQuery,cmdDetails.details.dMarker)){
state.PAGENAVIGATOR.dmarker = cmdDetails.details.dMarker;
}else{
//handling for incorrect dMarker
}
break;
case _.isUndefined(cmdDetails.details.teleport):
if(cmdDetails.details.teleport==='on'||cmdDetails.details.teleport==='off'){
state.PAGENAVIGATOR.teleport = cmdDetails.details.teleport;
}else{
sendChat('Page Navigator Error','/w "'+who+'" You attempted to turn teleportation on or off, but used an incorrect argument. You used "'+cmdDetails.details.teleport+'", but only "on" or "off" can be used.',null,{noarchive:true});
}
break;
case _.isUndefined(cmdDetails.details.tokens):
state.PAGENAVIGATOR.players[cmdDetails.details.tokens]=[];
_.each(cmdDetails.players,(p)=>{
if(p.length>0){
state.PAGENAVIGATOR.players[cmdDetails.details.tokens].push(p);
}
});
break;
default:
configAssembler(who);
}
},
//handles all logic for determining what move function to call
// object id object
moveHandler = function(cmdDetails,id,selected){
//4659
var page,token,character,folders;
if(cmdDetails.players.length===0 && selected){
_.each(selected,(s)=>{
token = getObj('graphic',s._id);
character = getObj('character',token.get('represents')) || token;
_.each(character.get('controlledby').split(','),(c)=>{
cmdDetails.players.push(c);
});
});
cmdDetails.players = _.reject(cmdDetails.players,(p)=>{return _.isUndefined(p);});
}
if(cmdDetails.details.page){
if(cmdDetails.details.page!=='return'){
try{
page = _.filter(allPages,(p)=>{
return p.get('name').replace(/\[[^\[\]]*\]/g,'').trim()===cmdDetails.details.page;
})[0].id;
}catch(err){
sendChat('Page Navigator Error:','/w "'+who+'" no page was found by the name '+cmdDetails.details.page,null,{noarchive:true});
return;
}
}else{
page = cmdDetails.details.page;
}
}else if(cmdDetails.details.pageID){
page = cmdDetails.details.pageID;
}
if(page && page!=='return'){
folders = getObj('page',page).get('name').match(/(?:\[([^\[\]]+)\])/g);
}
if(cmdDetails.players.length>0 && page && cmdDetails.details.landing!=='?'){
moveToPage(id,cmdDetails.players,page,cmdDetails.details.landing);
}else{
moveQuery(id,cmdDetails.action,cmdDetails.players,page,cmdDetails.details.landing)
}
},
help = function(id){
var who = idToDisplayName(id),
gm = playerIsGM(id),
msg = '
'//overall div for nice formatting of control panel
+'
'//Control Panel Header div
+'Page Navigator v'+version+' Help
'
+'For detailed help, access the Bio & Info tab of the
[Page Navigator Character](https://journal.roll20.net/character/'+state.PAGENAVIGATOR.help
+') for the full command and setup details. The available commands (with all possible options) are:'
+'
'
+'- !nav --config,[folder:FOLDERNAME,[access=gm/players] ],[control=whole/current/self],[dmarker=statusmarker/name],[teleport=on/off],[remove=on/off]
'
+'- !nav --move/teleport,[page=PAGENAME/return],[landing=LOCATION TEXT/?]|playerID/characterID|...
';
sendChat('Page Navigator','/w "'+who+'" '+msg,null,{noarchive:true});
},
//converts a playerid to their displayname
idToDisplayName = function(id){
var player = getObj('player', id);
if(player){
return player.get('displayname');
}else{
return 'gm';
}
},
setToken = function(tokens,whatValue,page){
//4651
var gnotes,settings;
_.each(tokens,(token)=>{
try{
settings = JSON.parse(decodeURIComponent(token.get('gmnotes')).split(/<[/]?.+?>/g).join(''));
}catch(e){
settings = {};
}
_.each(_.keys(whatValue),(w)=>{
settings[w]=whatValue[w] || settings[w];
});
if(page){
token.set('name',page);
}
if(state.PAGENAVIGATOR.dMarker !== 'name' && !token.get('status_'+state.PAGENAVIGATOR.dMarker)){
token.set(state.PAGENAVIGATOR.dMarker,true);
}
token.set('gmnotes',JSON.stringify(settings));
});
},
outputSetup = function(who,tokens){
//4675
var msg = '/w "'+who+'"
'//overall div for nice formatting of control panel
+'
'//Control Panel Header div
+'Page Navigator v'+version+' Destination Token Setup
'
+'This wizard will setup your selected destination token(s) with the appropriate JSON. Simply click each button to setup that aspect of the destination.',//Control Panel Header closing div
polygonButton,locationButton,llButton,chatButton,nameButton,nameButton,settings,llQuery,locationQuery,
pageQuery = '?{Which Page|'+_.map(allPages,(p)=>{return p.get('name').replace(/\[[^\[\]]*\]/g,'').trim();}).join('|')+'|**PAGE NOT CREATED YET**,?{Page Name to be Created'+HE(HE('}'))+'}',
tokenIDs = _.map(tokens,(t)=>{return t.id}).join('|');
try{
settings = JSON.parse(decodeURIComponent(tokens[0].get('gmnotes')).split(/<[/]?.+?>/g).join(''));
if(!settings.polygon){
settings.polygon = '#50dead';
}
}catch(e){
settings = {
location:'',
linkLocation:'',
polygon:undefined,
chat:''
};
}
llQuery = '?{Link to Which Location|'+_.map(destTokens[_.filter(allPages,(p)=>{return p.get('name').replace(/\[[^\[\]]*\]/g,'').trim()===tokens[0].get('name')})[0].id],(t)=>{
return t.parsedGM.location;
}).join('|')+'|**LOCATION NOT LISTED**,?{linkLocation Text Free Type'+HE(HE('}'))+'}';
locationQuery = '?{Describe This Location|'+_.map(destTokens[_.filter(allPages,(p)=>{return p.get('name').replace(/\[[^\[\]]*\]/g,'').trim()===tokens[0].get('name')})[0].id],(t)=>{
return t.parsedGM.linkLocation;
}).join('|')+'|**LOCATION NOT ALREADY LINKED**,?{location Text Free Type'+HE(HE('}'))+'}';
nameButton = makeButton(
'!nav --setup,page='+pageQuery+'|'+tokenIDs+' --setup|'+tokenIDs,
tokens[0].get('name'),'transparent','black'
);
polygonButton = makeButton(
'!nav --setup,polygon|'+tokenIDs+' --setup|'+tokenIDs,
'Select Boundary','transparent','black'
);
locationButton = makeButton(
'!nav --setup,location='+locationQuery+'|'+tokenIDs+' --setup|'+tokenIDs,
(settings.location || ''),'transparent','black'
);
llButton = makeButton(
'!nav --setup,linkLocation='+llQuery+'|'+tokenIDs+' --setup|'+tokenIDs,
(settings.linkLocation || ''),'transparent','black'
);
chatButton = makeButton(
'!nav --setup,chat=?{What chat command would you like sent. Currently set to'+HE(':')+' '+HE(HE((settings.chat || '')))+'}|'+tokenIDs+' --setup|'+tokenIDs,
'Enter Chat Command to run','transparent','black'
);
msg+='
'
+'**Token Name:**
'+nameButton+'
'
+'
'
+'**Boundary:**
'+polygonButton+'
'
+'
'
+'**Location Text:**
'+locationButton+'
'
+'
'
+'**linkLocation Text:**
'+llButton+'
'
+'
'
+'**Chat Command:**
'+chatButton+'
';
msg+='
';//overall closing div
sendChat('Page Navigator',msg,null,{noarchive:true});
},
setupHandler = function(playerid,cmdDetails,selected){
var page = cmdDetails.details.page,
settings = {
location : cmdDetails.details.location,
linkLocation : cmdDetails.details.linkLocation,
chat : cmdDetails.details.chat
},
tokens = _.map(cmdDetails.players,(p)=>{return getObj('graphic',p)}),
who = idToDisplayName(playerid);
tokens = _.reject(tokens,(t)=>{return _.isUndefined(t)});
_.each(selected,(s)=>{
var object = findObjs({id:s._id})[0];
if(object.get('type')==='graphic' && cmdDetails.players.length===0){
tokens.push(object);
}else if(object.get('type')==='path' && cmdDetails.details.polygon){
settings.polygon = settings.polygon || [];
settings.polygon.push(object.id);
}
});
if(tokens.length>0 && (settings.polygon || settings.location || settings.linkLocation || settings.chat || page)){
setToken(tokens,settings,page);
}else if(tokens.length>0){
outputSetup(who,tokens);
}else{
sendChat('Page Navigator','/w "'+who+'" You attempted to activate the Destination Token Wizard. This wizard requires that you have a destination token(s) selected when you activate the wizard.',null,{noarchive:true});
}
},
/*Self-explanatory, but handles chat input. Also passes the access of the user*/
handleInput = function(msg_orig){
var msg = _.clone(msg_orig),
cmdDetails,
args,
access;
if (msg.content.indexOf('!nav')!==0 || msg.playerid==='API') {
return;
}
if(playerIsGM(msg.playerid)) {
access = 'gm';
}else if(!playerIsGM(msg.playerid)){
access = 'player';
}
args = msg.content.split(/\s+--/);
args.shift();
if(args.length===0){
help(msg.playerid);
}
_.each(args,(a)=>{
cmdDetails = cmdExtract(a);
switch(cmdDetails.action){
case 'upgrade':
state.PAGENAVIGATOR.upgrade = true;
checkInstall();
break;
case 'help':
help(msg.playerid);
break;
case 'move' || 'teleport':
moveHandler(cmdDetails,msg.playerid,msg.selected,access);
break;
case 'config':
if(access==='gm'){
configHandler(msg.playerid,cmdDetails);
}else{
//message to player that configuration options are GM only
}
break;
case 'setup':
if(access==='gm'){
setupHandler(msg.playerid,cmdDetails,msg.selected);
}
break;
default:
help(msg.playerid);
}
});
},
cmdExtract = function(cmd){
var cmdSep = {
details:{}
},
vars,
details;
cmdSep.players = cmd.split('|');
details = cmdSep.players.shift();
cmdSep.players=_.map(cmdSep.players,(t)=>{
return t.trim();
});
cmdSep.action = details.match(/config|help|move|teleport|setup|upgrade/);
if(cmdSep.action){
cmdSep.action = cmdSep.action[0];
}
_.each(details.replace(cmdSep.action+',','').split(','),(d)=>{
vars=d.match(/(folder|access|control|dMarker|update|page|pageID|pMarker|teleport|tokens|remove|landing|location|linkLocation|chat|polygon|token)(?:\:|=)([^,]+)/) || null;
if(vars){
cmdSep.details[vars[1]]=vars[2];
}else{
cmdSep.details[d]=d;
}
});
return cmdSep;
},
destroyHandler = function(obj){
var index, pIDs;
switch(obj.get('type')){
case 'page':
maps[obj.id]=undefined;
_.each(allFolders,(f)=>{
f = _.reject(f,(ids)=>{
return ids===obj.id;
});
});
allPages=_.reject(allPages,(p)=>{
return p.id===obj.id;
});
break;
case 'graphic':
if(obj.get('layer')==='objects'){
_.each(maps[obj.get('pageid')],(m)=>{
if(_.contains(m.object,obj.id)){
index = m.object.indexOf(obj.id);
m.object = _.reject(m.object,(o)=>{
o === obj.id;
})
}
});
}else if(obj.get('layer')==='gmlayer'||obj.get('layer')==='map'){
if(_.contains(state.PAGENAVIGATOR.destinationids,obj.id)){
destTokens[obj.get('pageid')] = _.reject(destTokens[obj.get('pageid')],(o)=>{
return o.token.id===obj.id;
});
}
}
break;
case 'character':
pIDS = obj.get('controlledby').split(',');
_.each(pIDs,(id)=>{
if(_.contains(state.PAGENAVIGATOR.players[id],obj.id)){
index = state.PAGENAVIGATOR.players[id].indexOf(obj.id);
state.PAGENAVIGATOR.players[id].splice(index,1);
}
});
break;
case 'player':
players = _.reject(players,(p)=>{
return p.id === obj.id;
});
state.PAGENAVIGATOR.players[obj.id]=undefined;
playerTokens[obj.id]=undefined;
break;
//end of switch
}
},
changeHandler = function(obj,prev){
var oldpIDs,newpIDs,index;
switch(obj.get('type')){
case 'graphic':
//object layer
if(obj.get('layer')==='objects' && (obj.get('left')!==prev.left || obj.get('top')!== prev.top || obj.get('width')!==prev.width || obj.get('height')!==prev.height || obj.get('layer')!==prev.layer)){
getDestinationCollisions(obj);
//gm or map layer
}
break;
case 'page':
if(obj.get('name')!==prev.width){
loadFolders(obj);
storeFolders();
}
break;
case 'character':
if(obj.get('controlledby')!==prev.controlledby){
oldpIDs = obj.get('controlledby').split(',');
newpIDs = prev.controlledby.split(',');
oldpIDs = _.filter(oldpIDs,(oid)=>{
return (!_.contains(newpIDs,oid));
});
_.each(oldpIDs,(oid)=>{
state.PAGENAVIGATOR.players[oid] = _.reject(state.PAGENAVIGATOR.players[oid],(p)=>{
return p === obj.id;
});
});
}
break;
}
},
addHandler = function(obj){
switch(obj.get('type')){
case 'graphic':
if(obj.get('layer')==='gmlayer'){
loadDests(getObj('page',obj.get('pageid')));
}
break;
case 'page':
mapPage(obj);
loadfolders(obj);
storeFolders();
break;
case 'player':
state.PAGENAVIGATOR.players[obj.id]=[];
loadPlayers();
break;
//add Player add handling
}
},
RegisterEventHandlers = function() {
//message handling
on('chat:message', handleInput);
//graphic handling
on('add:graphic',addHandler);
on('change:graphic', changeHandler);
on('destroy:graphic',destroyHandler);
//character handling
on('add:character',addHandler);
on('change:character',changeHandler);
on('destroy:character',destroyHandler);
//page handling
on('add:page',addHandler);
on('change:page',changeHandler);
on('destroy:page',destroyHandler);
//player handling
on('add:player',addHandler);
on('destroy:player',destroyHandler);
};
return {
CheckInstall: checkInstall,
RegisterEventHandlers: RegisterEventHandlers
};
}());
on("ready",function(){
'use strict';
PAGENAVIGATOR.CheckInstall();
PAGENAVIGATOR.RegisterEventHandlers();
});